#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
智能电表系统 - 模拟数据生成脚本
此脚本用于在没有Arduino硬件的情况下生成模拟的电表数据，
并将数据发送到Flask服务端，用于测试整个系统的功能。
"""

import time
import random
import json
import requests
from datetime import datetime

class SmartMeterSimulator:
    """智能电表模拟器类"""
    
    def __init__(self, server_url='http://localhost:5000', update_interval=5):
        """
        初始化模拟器
        
        参数:
        server_url: Flask服务端的URL
        update_interval: 数据更新间隔（秒）
        """
        self.server_url = server_url
        self.update_interval = update_interval
        self.running = False
        
        # 设置电压和电流的基准值和波动范围
        self.base_voltage = 220.0
        self.voltage_range = 5.0
        self.base_current = 2.0
        self.current_range = 1.5
        
        # 上一次的用电量（kWh）
        self.previous_energy = 0
        self.last_timestamp = datetime.now().timestamp()
        
        print("智能电表模拟器初始化完成")
        print(f"服务端URL: {self.server_url}")
        print(f"更新间隔: {self.update_interval}秒")
        print("按Ctrl+C停止模拟")
        print("=" * 50)
    
    def generate_sensor_data(self):
        """生成模拟的传感器数据"""
        # 获取当前时间戳
        current_time = datetime.now()
        timestamp = current_time.timestamp()
        time_str = current_time.strftime('%Y-%m-%d %H:%M:%S')
        
        # 生成随机的电压和电流值
        voltage = self.base_voltage + (random.random() * self.voltage_range * 2 - self.voltage_range)
        current = self.base_current + (random.random() * self.current_range)
        
        # 根据时间调整用电模式
        hour = current_time.hour
        # 高峰期（早上7-9点，晚上18-22点）电流增加
        if (7 <= hour < 9) or (18 <= hour < 22):
            current *= 1.5 + random.random() * 0.5
        # 低谷期（凌晨0-6点）电流减少
        elif 0 <= hour < 6:
            current *= 0.5 + random.random() * 0.3
        
        # 计算功率
        power = voltage * current
        
        # 计算用电量（基于时间差）
        time_diff = timestamp - self.last_timestamp  # 秒
        energy_kwh = power * time_diff / 3600.0 / 1000.0  # 转换为kWh
        
        # 更新累积用电量和最后时间戳
        self.previous_energy += energy_kwh
        self.last_timestamp = timestamp
        
        # 构建数据字典
        data = {
            'timestamp': time_str,
            'voltage': round(voltage, 2),
            'current': round(current, 2),
            'power': round(power, 2),
            'energy': round(self.previous_energy, 3)
        }
        
        return data
    
    def send_data_to_server(self, data):
        """将数据发送到Flask服务端"""
        try:
            # 将数据转换为JSON格式
            json_data = json.dumps(data)
            
            # 发送POST请求到服务端
            response = requests.post(f"{self.server_url}/api/data", json=data, timeout=3)
            
            if response.status_code == 200:
                print(f"[{data['timestamp']}] 数据发送成功: 电压={data['voltage']}V, 电流={data['current']}A, 功率={data['power']}W, 用电量={data['energy']}kWh")
                return True
            else:
                print(f"[{data['timestamp']}] 数据发送失败: HTTP {response.status_code}")
                return False
        except requests.exceptions.RequestException as e:
            print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 请求异常: {str(e)}")
            return False
    
    def run(self):
        """运行模拟器"""
        self.running = True
        
        try:
            while self.running:
                # 生成模拟数据
                data = self.generate_sensor_data()
                
                # 发送数据到服务端
                self.send_data_to_server(data)
                
                # 等待下一次更新
                time.sleep(self.update_interval)
        except KeyboardInterrupt:
            print("\n模拟器已停止")
        except Exception as e:
            print(f"模拟过程中发生错误: {str(e)}")
        finally:
            self.running = False
    
    def stop(self):
        """停止模拟器"""
        self.running = False

if __name__ == '__main__':
    # 创建模拟器实例
    simulator = SmartMeterSimulator(
        server_url='http://localhost:5000',
        update_interval=5  # 每5秒更新一次
    )
    
    # 运行模拟器
    simulator.run()